#include "libRaid1.h"

extern uint32_t cantPPD;
extern uint64_t sectoresMaestros;
extern nodoLista *ppd;

extern pthread_mutex_t semaforoPPD;
extern pthread_mutex_t semaforoSectoresMaestros;
extern pthread_mutex_t semaforoCantPPD;

/* --------------------------------------------------------------------------------------------------- */
/*                                    RUTINA DE ATENCION AL CLIENTE                                    */
/* --------------------------------------------------------------------------------------------------- */

void atenderCliente(variablesCliente *variables) {
	// Si el RAID se encuentra en primer instancia (Desactivado) ----------------------------------------
	uint8_t descriptorVivo = 1;

	pthread_mutex_lock(&semaforoCantPPD);
	uint32_t cantPPDAux = cantPPD;
	pthread_mutex_unlock(&semaforoCantPPD);

	while (descriptorVivo) {
		memset(variables->bufCrudo, '\0', MAX_BUFFER);
		variables->bytesRecibidos = recv(variables->fileDescriptor, variables->bufCrudo, MAX_BUFFER, 0);

		if (variables->bytesRecibidos > 0) {
			if (variables->flagConsola == 1) {
				printf("Recibidos %i bytes del cliente numero %i \n", variables->bytesRecibidos, variables->numeroCliente);
			}
			variables->nuevoPaquete = empaquetar(variables->bufCrudo);

			procesarPaquete(variables->nuevoPaquete, &(variables->respuestaProcesamiento), &(variables->PPDidentificador), &(variables->PPDsectores), &(variables->PPDip), &(variables->PPDpuerto), &(variables->PPDidSize), &(variables->PPDipSize));

			// Si el paquete proviene de un File System -------------------------------------------------
			if (strcmp(variables->respuestaProcesamiento, "FS") == 0) {
				if (variables->flagConsola == 1) {
					printf("============================================================\n");
					printf("Cliente numero %i identificado como File System \n", variables->numeroCliente);
					printf("============================================================\n");
				}
				if (cantPPDAux == 0) {
					// Error: Cero Planificadores Conectados "ERROR0PLAN" -------------------------------
					variables->errorCeroPlanificadores[0] = 0;
					variables->errorCeroPlanificadores[1] = 0;
					variables->errorCeroPlanificadores[2] = 11;
					variables->errorCeroPlanificadores[3] = 'E';
					variables->errorCeroPlanificadores[4] = 'R';
					variables->errorCeroPlanificadores[5] = 'R';
					variables->errorCeroPlanificadores[6] = 'O';
					variables->errorCeroPlanificadores[7] = 'R';
					variables->errorCeroPlanificadores[8] = '0';
					variables->errorCeroPlanificadores[9] = 'P';
					variables->errorCeroPlanificadores[10] = 'L';
					variables->errorCeroPlanificadores[11] = 'A';
					variables->errorCeroPlanificadores[12] = 'N';
					variables->errorCeroPlanificadores[13] = '\0';

					if (variables->flagConsola == 1) {
						printf("Cantidad de Planificadores Conectados: %i \n", cantPPDAux);
						printf("Enviando mensaje de error <[%d]:%d:%c%c%c%c%c%c%c%c%c%c> \n", variables->errorCeroPlanificadores[0], ((variables->errorCeroPlanificadores[1] * 256) + variables->errorCeroPlanificadores[2]), variables->errorCeroPlanificadores[3], variables->errorCeroPlanificadores[4], variables->errorCeroPlanificadores[5], variables->errorCeroPlanificadores[6], variables->errorCeroPlanificadores[7], variables->errorCeroPlanificadores[8], variables->errorCeroPlanificadores[9], variables->errorCeroPlanificadores[10], variables->errorCeroPlanificadores[11], variables->errorCeroPlanificadores[12]);
					}

					if (send(variables->fileDescriptor, variables->errorCeroPlanificadores, 14, 0) == -1) {
						if (variables->flagConsola == 1) {
							printf("Error en el send() \n");
						}
						close(variables->fileDescriptor);
						descriptorVivo = 0;
					} else {
						if (variables->flagConsola == 1) {
							printf("Exito en el send() \n");
						}
					}
				} else {
					if (cantPPDAux >= 1) {

						pthread_mutex_lock(&semaforoPPD);
						nodoLista *proAux = (nodoLista*) malloc(sizeof(nodoLista));
						proAux = ppd;
						while (proAux != NULL) {
							matar(proAux->infoLista.id, variables->flagConsola);
						}
						pthread_mutex_lock(&semaforoCantPPD);
						uint32_t cantPPDAux10 = contarNodos();
						pthread_mutex_unlock(&semaforoCantPPD);
						pthread_mutex_unlock(&semaforoPPD);

						if (cantPPDAux10 == 0) {

							pthread_mutex_lock(&semaforoSectoresMaestros);
							sectoresMaestros = 0;
							pthread_mutex_unlock(&semaforoSectoresMaestros);

							// Error: Cero Planificadores Conectados "ERROR0PLAN" -------------------------------
							variables->errorCeroPlanificadores[0] = 0;
							variables->errorCeroPlanificadores[1] = 0;
							variables->errorCeroPlanificadores[2] = 11;
							variables->errorCeroPlanificadores[3] = 'E';
							variables->errorCeroPlanificadores[4] = 'R';
							variables->errorCeroPlanificadores[5] = 'R';
							variables->errorCeroPlanificadores[6] = 'O';
							variables->errorCeroPlanificadores[7] = 'R';
							variables->errorCeroPlanificadores[8] = '0';
							variables->errorCeroPlanificadores[9] = 'P';
							variables->errorCeroPlanificadores[10] = 'L';
							variables->errorCeroPlanificadores[11] = 'A';
							variables->errorCeroPlanificadores[12] = 'N';
							variables->errorCeroPlanificadores[13] = '\0';

							if (variables->flagConsola == 1) {
								printf("Cantidad de Planificadores Conectados: %i \n", cantPPDAux);
								printf("Enviando mensaje de error <[%d]:%d:%c%c%c%c%c%c%c%c%c%c> \n", variables->errorCeroPlanificadores[0], ((variables->errorCeroPlanificadores[1] * 256) + variables->errorCeroPlanificadores[2]), variables->errorCeroPlanificadores[3], variables->errorCeroPlanificadores[4], variables->errorCeroPlanificadores[5], variables->errorCeroPlanificadores[6], variables->errorCeroPlanificadores[7], variables->errorCeroPlanificadores[8], variables->errorCeroPlanificadores[9], variables->errorCeroPlanificadores[10], variables->errorCeroPlanificadores[11], variables->errorCeroPlanificadores[12]);
							}

							if (send(variables->fileDescriptor, variables->errorCeroPlanificadores, 14, 0) == -1) {
								if (variables->flagConsola == 1) {
									printf("Error en el send() \n");
								}
								close(variables->fileDescriptor);
								descriptorVivo = 0;
							} else {
								if (variables->flagConsola == 1) {
									printf("Exito en el send() \n");
								}
							}

						} else {

							if (send(variables->fileDescriptor, "\0\0\0", 3, 0) == -1) {
								if (variables->flagConsola == 1) {
									printf("Error en el send() \n");
								}
								close(variables->fileDescriptor);
								descriptorVivo = 0;
							} else {
								if (variables->flagConsola == 1) {
									printf("Handshake exitoso() \n");
								}
							}

							while (descriptorVivo) {

								memset(variables->bufCrudo, '\0', MAX_BUFFER);

								if (recv(variables->fileDescriptor, variables->bufCrudo, MAX_BUFFER, 0) == -1) {
									if (variables->flagConsola == 1) {
										printf("Error en el recv() \n");
									}
									close(variables->fileDescriptor);
									descriptorVivo = 0;
								} else {
									if (variables->flagConsola == 1) {
										printf("Exito en el recv() \n");
									}

									pthread_mutex_lock(&semaforoPPD);
									nodoLista *nodoDisponible = (nodoLista*) malloc(sizeof(nodoLista));
									while (matar(nodoConMenosTiempo()->infoLista.id, variables->flagConsola)) {
										;
									}
									nodoDisponible = nodoConMenosTiempo();
									pthread_mutex_lock(&semaforoCantPPD);
									uint32_t cantPPDAux5 = contarNodos();
									pthread_mutex_unlock(&semaforoCantPPD);

									if (cantPPDAux5 != 0) {

										uint32_t descriptorPPD = nodoDisponible->infoLista.fileDescriptor;

										variables->nuevoPaquete = empaquetar(variables->bufCrudo);

										procesarPaquete(variables->nuevoPaquete, &(variables->respuestaProcesamiento), &(variables->PPDidentificador), &(variables->PPDsectores), &(variables->PPDip), &(variables->PPDpuerto), &(variables->PPDidSize), &(variables->PPDipSize));

										if (strcmp(variables->respuestaProcesamiento, "Lei") == 0) {

											// Si el paquete es de tipo READ ----------------------------------------
											if (variables->flagConsola == 1) {
												printf("------------------------------------------------------------\n");
												printf("Recibido paquete de Lectura \n");
												printf("------------------------------------------------------------\n");
											}

											if (send(descriptorPPD, variables->bufCrudo, MAX_BUFFER, 0) != -1) {
												if (recv(descriptorPPD, variables->bufTiempo, BUFFER_TIEMPO, 0) != -1) {
													if (recv(descriptorPPD, variables->buferLectura, MAX_BUFFER, 0) != -1) {
														if (send(variables->fileDescriptor, variables->buferLectura, MAX_BUFFER, 0) != -1) {
															nodoDisponible->infoLista.tiempoDeEspera = (((uint8_t) variables->bufTiempo[3]) * potencia(2, 56)) + (((uint8_t) variables->bufTiempo[4]) * potencia(2, 48)) + (((uint8_t) variables->bufTiempo[5]) * potencia(2, 40)) + (((uint8_t) variables->bufTiempo[6]) * potencia(2, 32)) + (((uint8_t) variables->bufTiempo[7]) * potencia(2, 24)) + (((uint8_t) variables->bufTiempo[8]) * potencia(2, 16)) + (((uint8_t) variables->bufTiempo[9]) * potencia(2, 8)) + (((uint8_t) variables->bufTiempo[10]) * potencia(2, 0));
															if (variables->flagConsola == 1) {
																printf("Lectura efectuada satisfactoriamente desde el planificador <%s> (%i)\n", nodoDisponible->infoLista.id, nodoDisponible->infoLista.tiempoDeEspera);
																printf("------------------------------------------------------------\n");
															}
														} else {
															if (variables->flagConsola == 1) {
																printf("Error en el send() \n");
															}
															close(variables->fileDescriptor);
															descriptorVivo = 0;
														}
													} else {
														close(nodoDisponible->infoLista.fileDescriptor);
														buscarQuitar(nodoDisponible->infoLista.id);
														if (variables->flagConsola) {
															printf("Planificador <%s> desconectado \n", nodoDisponible->infoLista.id);
															printf("Eliminando nodo \n");
															printf("------------------------------------------------------------\n");
															printf("Lista de planificadores resultante \n");
															imprimirLista();
														}
													}
												} else {
													close(nodoDisponible->infoLista.fileDescriptor);
													buscarQuitar(nodoDisponible->infoLista.id);
													if (variables->flagConsola) {
														printf("Planificador <%s> desconectado \n", nodoDisponible->infoLista.id);
														printf("Eliminando nodo \n");
														printf("------------------------------------------------------------\n");
														printf("Lista de planificadores resultante \n");
														imprimirLista();

													}
												}
											} else {
												close(nodoDisponible->infoLista.fileDescriptor);
												buscarQuitar(nodoDisponible->infoLista.id);
												if (variables->flagConsola) {
													printf("Planificador <%s> desconectado \n", nodoDisponible->infoLista.id);
													printf("Eliminando nodo \n");
													printf("------------------------------------------------------------\n");
													printf("Lista de planificadores resultante \n");
													imprimirLista();
												}
											}
										} else {
											// Si el paquete es de tipo WRITE ---------------------------------------
											if (strcmp(variables->respuestaProcesamiento, "Escribi") == 0) {
												if (variables->flagConsola == 1) {
													printf("------------------------------------------------------------\n");
													printf("Recibido paquete de Escritura \n");
													printf("------------------------------------------------------------\n");
												}
												if (send(descriptorPPD, variables->bufCrudo, MAX_BUFFER, 0) != -1) {
													if (recv(descriptorPPD, variables->bufTiempo, BUFFER_TIEMPO, 0) != -1) {
														nodoDisponible->infoLista.tiempoDeEspera = (((uint8_t) variables->bufTiempo[3]) * potencia(2, 56)) + (((uint8_t) variables->bufTiempo[4]) * potencia(2, 48)) + (((uint8_t) variables->bufTiempo[5]) * potencia(2, 40)) + (((uint8_t) variables->bufTiempo[6]) * potencia(2, 32)) + (((uint8_t) variables->bufTiempo[7]) * potencia(2, 24)) + (((uint8_t) variables->bufTiempo[8]) * potencia(2, 16)) + (((uint8_t) variables->bufTiempo[9]) * potencia(2, 8)) + (((uint8_t) variables->bufTiempo[10]) * potencia(2, 0));

														char *confirmacionEscritura = (char*) malloc(sizeof(char) * 11);
														confirmacionEscritura[0] = 0;
														confirmacionEscritura[1] = 0;
														confirmacionEscritura[2] = 8;
														confirmacionEscritura[3] = 'E';
														confirmacionEscritura[4] = 'S';
														confirmacionEscritura[5] = 'C';
														confirmacionEscritura[6] = 'R';
														confirmacionEscritura[7] = 'I';
														confirmacionEscritura[8] = 'B';
														confirmacionEscritura[9] = 'I';
														confirmacionEscritura[10] = '\0';

														if (variables->flagConsola == 1) {
															printf("Escritura enviada satisfactoriamente al planificador <%s> \n", nodoDisponible->infoLista.id);
															printf("Enviando mensaje de confirmacion <[%d]:%d:%c%c%c%c%c%c%c> \n", confirmacionEscritura[0], ((confirmacionEscritura[1] * 256) + confirmacionEscritura[2]), confirmacionEscritura[3], confirmacionEscritura[4], confirmacionEscritura[5], confirmacionEscritura[6], confirmacionEscritura[7], confirmacionEscritura[8], confirmacionEscritura[9]);
														}

														if (send(variables->fileDescriptor, confirmacionEscritura, 11, 0) == -1) {
															if (variables->flagConsola == 1) {
																printf("Error en el send() \n");
															}
															close(variables->fileDescriptor);
															descriptorVivo = 0;
														} else {
															if (variables->flagConsola == 1) {
																printf("Exito en el send() \n");
															}
														}

													} else {
														buscarQuitar(ppd->infoLista.id);
														if (variables->flagConsola == 1) {
															printf("Error asignando escritura al planificador <%s> \n", ppd->infoLista.id);
															printf("Eliminando nodo \n");
															printf("------------------------------------------------------------\n");
															printf("Lista de planificadores resultante \n");
															imprimirLista();
														}
													}
												} else {
													buscarQuitar(ppd->infoLista.id);
													if (variables->flagConsola == 1) {
														printf("Error asignando escritura al planificador <%s> \n", ppd->infoLista.id);
														printf("Eliminando nodo \n");
														printf("------------------------------------------------------------\n");
														printf("Lista de planificadores resultante \n");
														imprimirLista();
													}
												}
											}
										}
									} else {
										// Error: Cero Planificadores Conectados "ERROR0PLAN" -------------------------------
										variables->errorCeroPlanificadores[0] = 0;
										variables->errorCeroPlanificadores[1] = 0;
										variables->errorCeroPlanificadores[2] = 11;
										variables->errorCeroPlanificadores[3] = 'E';
										variables->errorCeroPlanificadores[4] = 'R';
										variables->errorCeroPlanificadores[5] = 'R';
										variables->errorCeroPlanificadores[6] = 'O';
										variables->errorCeroPlanificadores[7] = 'R';
										variables->errorCeroPlanificadores[8] = '0';
										variables->errorCeroPlanificadores[9] = 'P';
										variables->errorCeroPlanificadores[10] = 'L';
										variables->errorCeroPlanificadores[11] = 'A';
										variables->errorCeroPlanificadores[12] = 'N';
										variables->errorCeroPlanificadores[13] = '\0';

										if (variables->flagConsola == 1) {
											printf("Cantidad de Planificadores Conectados: %i \n", cantPPDAux);
											printf("Enviando mensaje de error <[%d]:%d:%c%c%c%c%c%c%c%c%c%c> \n", variables->errorCeroPlanificadores[0], ((variables->errorCeroPlanificadores[1] * 256) + variables->errorCeroPlanificadores[2]), variables->errorCeroPlanificadores[3], variables->errorCeroPlanificadores[4], variables->errorCeroPlanificadores[5], variables->errorCeroPlanificadores[6], variables->errorCeroPlanificadores[7], variables->errorCeroPlanificadores[8], variables->errorCeroPlanificadores[9], variables->errorCeroPlanificadores[10], variables->errorCeroPlanificadores[11], variables->errorCeroPlanificadores[12]);
										}

										if (send(variables->fileDescriptor, variables->errorCeroPlanificadores, 14, 0) == -1) {
											if (variables->flagConsola == 1) {
												printf("Error en el send() \n");
											}
											close(variables->fileDescriptor);
											descriptorVivo = 0;
										} else {
											if (variables->flagConsola == 1) {
												printf("Exito en el send() \n");
											}
										}
									}
									pthread_mutex_unlock(&semaforoPPD);
								}
							}
						}
					}
				}
			} else {
				// Si el paquete proviene de un Planificador de Discos ----------------------------------
				pthread_mutex_lock(&semaforoSectoresMaestros);
				pthread_mutex_lock(&semaforoPPD);
				if (variables->flagConsola == 1) {
					printf("============================================================\n");
					printf("Cliente numero %i identificado como Planificador de Discos \n", variables->numeroCliente);
					printf("============================================================\n");
					printf("Lista de Planificadores Actual \n");
					imprimirLista();
					printf("------------------------------------------------------------\n");
					printf("Bufer recibido: ");
					printf("< ID(%s) | ", variables->PPDidentificador);
					printf("S(%i) | ", variables->PPDsectores);
					printf("IP(%s) | ", variables->PPDip);
					printf("P(%i) >", variables->PPDpuerto);
					printf("\n");
					printf("------------------------------------------------------------\n");
				}

				descriptorVivo = 0;

				nodoLista *proAux = (nodoLista*) malloc(sizeof(nodoLista));
				proAux = ppd;
				while (proAux != NULL) {
					matar(proAux->infoLista.id, variables->flagConsola);
				}

				// Si el Planificador ya existe ---------------------------------------------------------
				uint32_t existePPDAux = existePPD(variables->PPDidentificador);

				if (existePPDAux == 1) {

					// Error: Planificador ya conectado "ERRORYAEXISTE" ---------------------------------
					variables->errorYaExiste[0] = 0;
					variables->errorYaExiste[1] = 0;
					variables->errorYaExiste[2] = 13;
					variables->errorYaExiste[3] = 'E';
					variables->errorYaExiste[4] = 'R';
					variables->errorYaExiste[5] = 'R';
					variables->errorYaExiste[6] = 'O';
					variables->errorYaExiste[7] = 'R';
					variables->errorYaExiste[8] = 'Y';
					variables->errorYaExiste[9] = 'A';
					variables->errorYaExiste[10] = 'E';
					variables->errorYaExiste[11] = 'X';
					variables->errorYaExiste[12] = 'I';
					variables->errorYaExiste[13] = 'S';
					variables->errorYaExiste[14] = 'T';
					variables->errorYaExiste[15] = 'E';

					if (variables->flagConsola == 1) {
						printf("Planificador <%s> ya conectado \n", variables->PPDidentificador);
						printf("Enviando mensaje de error <[%d]:%i:%c%c%c%c%c%c%c%c%c%c%c%c%c> \n", variables->errorYaExiste[0], ((variables->errorYaExiste[1] * 256) + variables->errorYaExiste[2]), variables->errorYaExiste[3], variables->errorYaExiste[4], variables->errorYaExiste[5], variables->errorYaExiste[6], variables->errorYaExiste[7], variables->errorYaExiste[8], variables->errorYaExiste[9], variables->errorYaExiste[10], variables->errorYaExiste[11], variables->errorYaExiste[12], variables->errorYaExiste[13], variables->errorYaExiste[14], variables->errorYaExiste[15]);
					}

					if (send(variables->fileDescriptor, variables->errorYaExiste, 16, 0) == -1) {
						if (variables->flagConsola == 1) {
							printf("Exito en el send() \n");
						}
					} else {
						if (variables->flagConsola == 1) {
							printf("Error en el send() \n");
						}
						close(variables->fileDescriptor);
						descriptorVivo = 0;
					}
				} else {
					// Si el Planificador Actual tiene menos sectores que el Planificador Maestro -------
					if (variables->PPDsectores < sectoresMaestros) {
						// Error: Sectores Insuficientes "ERRORSECTINS" ---------------------------------
						variables->errorSectoresInsuficientes[0] = 0;
						variables->errorSectoresInsuficientes[1] = 0;
						variables->errorSectoresInsuficientes[2] = 12;
						variables->errorSectoresInsuficientes[3] = 'E';
						variables->errorSectoresInsuficientes[4] = 'R';
						variables->errorSectoresInsuficientes[5] = 'R';
						variables->errorSectoresInsuficientes[6] = 'O';
						variables->errorSectoresInsuficientes[7] = 'R';
						variables->errorSectoresInsuficientes[8] = 'S';
						variables->errorSectoresInsuficientes[9] = 'E';
						variables->errorSectoresInsuficientes[10] = 'C';
						variables->errorSectoresInsuficientes[11] = 'T';
						variables->errorSectoresInsuficientes[12] = 'I';
						variables->errorSectoresInsuficientes[13] = 'N';
						variables->errorSectoresInsuficientes[14] = 'S';

						if (variables->flagConsola == 1) {
							printf("Sectores del planificador maestro: [%i] \n", sectoresMaestros);
							printf("El planificador <%s> no posee sectores suficientes (%i<%i) \n", variables->PPDidentificador, variables->PPDsectores, sectoresMaestros);
							printf("Enviando mensaje de error <[%d]:%i:%c%c%c%c%c%c%c%c%c%c%c%c> \n", variables->errorSectoresInsuficientes[0], ((variables->errorSectoresInsuficientes[1] * 256) + variables->errorSectoresInsuficientes[2]), variables->errorSectoresInsuficientes[3], variables->errorSectoresInsuficientes[4], variables->errorSectoresInsuficientes[5], variables->errorSectoresInsuficientes[6], variables->errorSectoresInsuficientes[7], variables->errorSectoresInsuficientes[8], variables->errorSectoresInsuficientes[9], variables->errorSectoresInsuficientes[10], variables->errorSectoresInsuficientes[11], variables->errorSectoresInsuficientes[12], variables->errorSectoresInsuficientes[13], variables->errorSectoresInsuficientes[14]);
						}

						if (send(variables->fileDescriptor, variables->errorSectoresInsuficientes, 15, 0) == -1) {
							if (variables->flagConsola == 1) {
								printf("Error en el send() \n");
							}
							close(variables->fileDescriptor);
							descriptorVivo = 0;
						} else {
							if (variables->flagConsola == 1) {
								printf("Exito en el send() \n");
							}
						}
					} else {
						if (existePPDAux == 0) {
							// Agrego el Planificador -------------------------------------------------------
							tInfoLista registroNuevo;

							registroNuevo.id = (char*) malloc(sizeof(char) * (variables->PPDidSize));
							registroNuevo.ip = (char*) malloc(sizeof(char) * (variables->PPDipSize));

							strcpy(registroNuevo.id, variables->PPDidentificador);
							strcpy(registroNuevo.ip, variables->PPDip);
							registroNuevo.puerto = variables->PPDpuerto;
							registroNuevo.tiempoDeEspera = 0;
							registroNuevo.fileDescriptor = variables->fileDescriptor;

							insertarFIFO(registroNuevo);

							if (variables->flagConsola == 1) {
								printf("Planificador <%s> agregado exitosamente \n", ppd->infoLista.id);
								printf("------------------------------------------------------------\n");
								printf("Lista de Planificadores Resultante \n");
								imprimirLista();
								printf("------------------------------------------------------------\n");
							}

							if (send(variables->fileDescriptor, "\0\0\0", 3, 0) == -1) {
								if (variables->flagConsola == 1) {
									printf("Error en el send()\n");
								}
								close(variables->fileDescriptor);
								descriptorVivo = 0;
							} else {
								if (variables->flagConsola == 1) {
									printf("Exito en el send() \n");
									printf("------------------------------------------------------------\n");
									printf("Handshake con <%s> exitoso \n", ppd->infoLista.id);
								}
							}

							pthread_mutex_lock(&semaforoCantPPD);
							uint64_t contarNodosAux = contarNodos();
							pthread_mutex_unlock(&semaforoCantPPD);

							if (contarNodosAux >= 2) {
								if (variables->flagConsola == 1) {
									printf("============================================================\n");
								}

								nodoLista *nodoInicial = (nodoLista*) malloc(sizeof(nodoLista));

								nodoInicial = nodoConMenosTiempo();

								pthread_mutex_lock(&semaforoCantPPD);
								uint64_t contarNodosAux87 = contarNodos();
								pthread_mutex_unlock(&semaforoCantPPD);

								if (contarNodosAux87 >= 2) {
									nodoLista *nodoSincronizacion = (nodoLista*) malloc(sizeof(nodoLista));
									nodoSincronizacion = nodoInicial;

									if (variables->flagConsola == 1) {
										printf("Comienza sincronizacion de disco <%s> con disco <%s> \n", variables->PPDidentificador, nodoSincronizacion->infoLista.id);
										printf("============================================================\n");
									}

									uint32_t c1;
									uint32_t desconectado = 0;

									for (c1 = 0; (c1 < sectoresMaestros) && (!desconectado); c1++) {
										variables->paqueteLectura.type = 1;
										variables->paqueteLectura.pLength = 8;
										variables->paqueteLectura.payLoad[0] = c1;

										paqueteLecturaAPaquete(variables->paqueteLectura, &variables->paqueteSincro);
										desempaquetar(variables->paqueteSincro, &variables->paqueteSincroDescerealizado);

										if (variables->flagConsola == 1) {
											printf("Sincronizando sector %d ... ", c1);
										}

										char *confirmacion = (char*) malloc(sizeof(char) * 11);

										if (send(nodoSincronizacion->infoLista.fileDescriptor, variables->paqueteSincroDescerealizado, MAX_BUFFER, 0) != -1) {
											if (recv(nodoSincronizacion->infoLista.fileDescriptor, variables->buferLectura, MAX_BUFFER, 0) != -1) {
												if (send(variables->fileDescriptor, variables->buferLectura, MAX_BUFFER, 0) != -1) {
													if (recv(variables->fileDescriptor, confirmacion, 11, 0)) {
														if (variables->flagConsola == 1) {
															printf("Exito \n");
														}
													} else {
														close(variables->fileDescriptor);
														buscarQuitar(variables->PPDidentificador);
														desconectado = 2;
														if (variables->flagConsola == 1) {
															printf("Planificador desconectado \n");
															printf("Eliminando nodo \n");
															printf("------------------------------------------------------------\n");
															printf("Lista resultante \n");
															imprimirLista();
														}
													}
												} else {
													close(variables->fileDescriptor);
													buscarQuitar(variables->PPDidentificador);
													desconectado = 2;
													if (variables->flagConsola == 1) {
														printf("Planificador desconectado \n");
														printf("Eliminando nodo \n");
														printf("------------------------------------------------------------\n");
														printf("Lista resultante \n");
														imprimirLista();
													}
												}
											} else {
												close(nodoSincronizacion->infoLista.fileDescriptor);
												buscarQuitar(variables->nodoSincronizacion->infoLista.id);

												pthread_mutex_lock(&semaforoCantPPD);
												uint32_t cantPPDAux6969 = contarNodos();
												pthread_mutex_unlock(&semaforoCantPPD);

												if (cantPPDAux6969 < 2) {
													if (variables->flagConsola == 1) {
														printf("Sincronizacion cancelada \n");
													}
												} else {
													nodoSincronizacion = nodoConMenosTiempo();
													if (variables->flagConsola == 1) {
														printf("Sincronizacion del sector <%d> reasignada al planificador <%s> \n", c1, nodoSincronizacion->infoLista.id);
													}
													c1--;
												}
											}
										} else {
											close(nodoSincronizacion->infoLista.fileDescriptor);
											buscarQuitar(variables->nodoSincronizacion->infoLista.id);

											pthread_mutex_lock(&semaforoCantPPD);
											uint32_t cantPPDAux6969 = contarNodos();
											pthread_mutex_unlock(&semaforoCantPPD);

											if (cantPPDAux6969 < 2) {
												if (variables->flagConsola == 1) {
													printf("Sincronizacion cancelada \n");
												}
											} else {
												nodoSincronizacion = nodoConMenosTiempo();
												if (variables->flagConsola == 1) {
													printf("Sincronizacion del sector <%d> reasignada al planificador <%s> \n", c1, nodoSincronizacion->infoLista.id);
												}
												c1--;
											}
										}
										if (!desconectado && (c1 == sectoresMaestros)) {
											if (variables->flagConsola == 1) {
												printf("============================================================\n");
												printf("     _                            _               _             \n");
												printf("    (_)                          (_)             (_)            \n");
												printf(" ___ _ _ __   ___ _ __ ___  _ __  _ ______ _  ___ _  ___  _ __  \n");
												printf("/ __| | '_ \\ / __| '__/ _ \\| '_ \\| |_  / _` |/ __| |/ _ \\| '_ \\ \n");
												printf("\\__ \\ | | | | (__| | | (_) | | | | |/ / (_| | (__| | (_) | | | |\n");
												printf("|___/_|_| |_|\\___|_|  \\___/|_| |_|_/___\\__,_|\\___|_|\\___/|_| |_|\n");
												printf("                                     _      _         \n");
												printf("                                    | |    | |        \n");
												printf("           ___  ___  _ __ ___  _ __ | | ___| |_  __ _ \n");
												printf("          / __|/ _ \\| '_ ` _ \\| '_ \\| |/ _ \\ __|/ _` |\n");
												printf("         | (__| (_) | | | | | | |_) | |  __/ |_| (_| |\n");
												printf("          \\___|\\___/|_| |_| |_| .__/|_|\\___|\\__|\\__,_|\n");
												printf("                              | |                     \n");
												printf("                              |_|                     \n\n");
											}
										}
									}
								}
							} else {
								if (contarNodosAux == 1) {
									// Si el planificador agregado era el primero
									sectoresMaestros = variables->PPDsectores;
									if (variables->flagConsola == 1) {
										printf("<%s> pasa a ser el planificador maestro con %i sectores \n", variables->PPDidentificador, sectoresMaestros);

									}
								}
							}
						}
					}
				}
				pthread_mutex_unlock(&semaforoPPD);
				pthread_mutex_unlock(&semaforoSectoresMaestros);
			}
		}
	}
}

/* --------------------------------------------------------------------------------------------------- */
/*                                             CONECTAR                                             */
/* --------------------------------------------------------------------------------------------------- */

uint32_t conectar(char* ip, uint32_t puerto) {
	uint32_t fileDescriptor = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in *remote_address = malloc(sizeof(struct sockaddr_in));
	{
		remote_address->sin_family = AF_INET;
		remote_address->sin_addr.s_addr = inet_addr(ip);
		remote_address->sin_port = htons(puerto);
	}
	if (connect(fileDescriptor, (struct sockaddr *) remote_address, sizeof(struct sockaddr_in)) == -1) {
		fileDescriptor = -1;
	}
	return fileDescriptor;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                         DESEMPAQUETAR                                               */
/* --------------------------------------------------------------------------------------------------- */

int8_t desempaquetar(t_paquete paquete, char** cadena) {
	(*cadena) = (char*) malloc(paquete.pLength + 3);
	(*cadena)[0] = paquete.type;
	div_t division = div(paquete.pLength, 255);
	(*cadena)[1] = division.quot;
	(*cadena)[2] = division.rem;
	uint32_t i;
	for (i = 3; i < paquete.pLength + 3; i++) {
		(*cadena)[i] = paquete.payLoad[i - 3];
	}
	return 0;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                      NODO CON MENOS TIEMPO                                          */
/* --------------------------------------------------------------------------------------------------- */
/* Devuelve el nodo con menor tiempo de espera de la lista <ppd>                                       */
/* --------------------------------------------------------------------------------------------------- */

nodoLista *nodoConMenosTiempo(void) {
	nodoLista *proAux = (nodoLista*) malloc(sizeof(nodoLista));
	nodoLista *nodoActual = (nodoLista*) malloc(sizeof(nodoLista));
	if (ppd != NULL) {
		proAux = ppd;
		uint32_t tiempoActual = proAux->infoLista.tiempoDeEspera;
		while (proAux != NULL) {
			if (proAux->infoLista.tiempoDeEspera < tiempoActual) {
				tiempoActual = proAux->infoLista.tiempoDeEspera;
				nodoActual = proAux;
			}
			proAux = proAux->sig;
		}
		free(proAux);
	}
	return nodoActual;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                           BUSCAR NODO                                               */
/* --------------------------------------------------------------------------------------------------- */
/* Devuelve el nodo de la lista <ppd> cuyo identificador es <identificador>                            */
/* --------------------------------------------------------------------------------------------------- */

nodoLista *buscarNodo(char *identificador) {
	nodoLista *proAux = (nodoLista*) malloc(sizeof(nodoLista));
	proAux = ppd;
	while (proAux != NULL && strcmp(proAux->infoLista.id, identificador) != 0) {
		proAux = proAux->sig;
	}
	return proAux;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                    PAQUETE LECTURA --> PAQUETE                                      */
/* --------------------------------------------------------------------------------------------------- */
/* Transforma el paquete <paqueteLectura> en un paquete de <t_paquete>                                 */
/* Devuelve en <paquete> el nuevo paquete                                                              */
/* --------------------------------------------------------------------------------------------------- */

int8_t esPaqueteLectura(char tipo) {
//<2><uint16_t><{<uint64_t>}>
	if (tipo == 1)
		return 1;
	else
		return 0;
}

int8_t paqueteLecturaAPaquete(t_paquete_lectura paqueteLectura, t_paquete* paquete) {
	if (esPaqueteLectura(paqueteLectura.type)) {
		(*paquete).type = paqueteLectura.type;
		(*paquete).pLength = paqueteLectura.pLength;
		(*paquete).payLoad = (char*) malloc(paqueteLectura.pLength);
		uint32_t i; //INDICE PARA CHAR
		uint32_t j; //INDICE PARA UINT64_T
		for (i = 0, j = 0; (i < paqueteLectura.pLength - 7) && (j < (paqueteLectura.pLength / sizeof(uint64_t))); i += 8, j++) {
			(*paquete).payLoad[i] = paqueteLectura.payLoad[j] / potencia(2, 56);
			(*paquete).payLoad[i + 1] = (paqueteLectura.payLoad[j] / potencia(2, 48)) - (((uint8_t) (*paquete).payLoad[i]) * potencia(2, 8));
			(*paquete).payLoad[i + 2] = (paqueteLectura.payLoad[j] / potencia(2, 40)) - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 8)));
			(*paquete).payLoad[i + 3] = (paqueteLectura.payLoad[j] / potencia(2, 32)) - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 24)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 2]) * potencia(2, 8)));
			(*paquete).payLoad[i + 4] = (paqueteLectura.payLoad[j] / potencia(2, 24)) - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 32)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 24)) + (((uint8_t) (*paquete).payLoad[i + 2]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 3]) * potencia(2, 8)));
			(*paquete).payLoad[i + 5] = (paqueteLectura.payLoad[j] / potencia(2, 16)) - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 40)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 32)) + (((uint8_t) (*paquete).payLoad[i + 2]) * potencia(2, 24)) + (((uint8_t) (*paquete).payLoad[i + 3]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 4]) * potencia(2, 8)));
			(*paquete).payLoad[i + 6] = (paqueteLectura.payLoad[j] / potencia(2, 8)) - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 48)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 40)) + (((uint8_t) (*paquete).payLoad[i + 2]) * potencia(2, 32)) + (((uint8_t) (*paquete).payLoad[i + 3]) * potencia(2, 24)) + (((uint8_t) (*paquete).payLoad[i + 4]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 5]) * potencia(2, 8)));
			(*paquete).payLoad[i + 7] = paqueteLectura.payLoad[j] - ((((uint8_t) (*paquete).payLoad[i]) * potencia(2, 56)) + (((uint8_t) (*paquete).payLoad[i + 1]) * potencia(2, 48)) + (((uint8_t) (*paquete).payLoad[i + 2]) * potencia(2, 40)) + (((uint8_t) (*paquete).payLoad[i + 3]) * potencia(2, 32)) + (((uint8_t) (*paquete).payLoad[i + 4]) * potencia(2, 24)) + (((uint8_t) (*paquete).payLoad[i + 5]) * potencia(2, 16)) + (((uint8_t) (*paquete).payLoad[i + 6]) * potencia(2, 8)));
		}
		return 0;
	} else
		return 1;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                            CONTAR NODOS                                             */
/* --------------------------------------------------------------------------------------------------- */
/* Devuelve la cantidad de nodos que hay en <ppd>                                                      */
/* --------------------------------------------------------------------------------------------------- */

uint32_t contarNodos(void) {
	nodoLista *aux = ppd;
	uint32_t cantNodos = 0;
	if (aux != NULL) {
		while (aux != NULL) {
			cantNodos++;
			aux = aux->sig;
		}
	}
	return cantNodos;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                            INSERTAR NODO                                            */
/* --------------------------------------------------------------------------------------------------- */
/* Inserta <valor> en la lista <ppd>                                                                   */
/* --------------------------------------------------------------------------------------------------- */

void insertarFIFO(tInfoLista valor) {
	nodoLista *aux = (nodoLista*) malloc(sizeof(nodoLista));
	aux->infoLista = valor;
	aux->sig = ppd;
	ppd = aux;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                VERIFICAR EXISTENCIA DEL PLANIFICADOR                                */
/* --------------------------------------------------------------------------------------------------- */
/* Recorre la lista <ppd> buscando <identificador>.                                                    */
/* Si lo encuentra, devuelve 1.                                                                        */
/* Si no lo encuentra, devuelve 0.                                                                     */
/* --------------------------------------------------------------------------------------------------- */

uint32_t existePPD(char *identificador) {
	nodoLista *aux = ppd;
	uint32_t boolean = 0;
	if (aux != NULL) {
		while ((aux != NULL) && (boolean == 0)) {
			if (strcmp(identificador, aux->infoLista.id) == 0) {
				boolean = 1;
			}
			aux = aux->sig;
		}
	}
	return boolean;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                             QUITAR NODO                                             */
/* --------------------------------------------------------------------------------------------------- */
/* Quita de la lista <ppd> el nodo cuyo identificador sea <identificador>.                             */
/* No devuelve ningun valor.                                                                           */
/* --------------------------------------------------------------------------------------------------- */

void buscarQuitar(char *identificador) {
	nodoLista *aux = ppd;
	nodoLista *anterior = (nodoLista*) malloc(sizeof(nodoLista));
	uint32_t nodo = 1;
	anterior = NULL;
	if (aux != NULL) {
		while ((strcmp(aux->infoLista.id, identificador) != 0) && (aux != NULL)) {
			anterior = aux;
			aux = aux->sig;
			nodo++;
		}
		if (aux != NULL && nodo >= 2) {
			anterior->sig = aux->sig;
			free(aux);
		} else {
			if (aux != NULL && nodo == 1) {
				ppd = aux->sig;
				free(aux);
			}
		}
	}
}

/* --------------------------------------------------------------------------------------------------- */
/*                                    CONFIRMACION DE DISPONIBILIDAD                                   */
/* --------------------------------------------------------------------------------------------------- */
/* Envia el mensaje "4\0\0" al <fileDescriptor>                                                        */
/* En caso de recibir como respuesta un "si", devuelve el valor 1                                      */
/* En caso de no recibir nada, o recibir cualquier otra cosa, devuelve el valor 0                      */
/* --------------------------------------------------------------------------------------------------- */

uint16_t confirmacion(uint32_t fileDescriptor) {
	uint16_t boolean = 0;
	char *bufRespuesta = (char*) malloc(sizeof(char) * 2);
	if (send(fileDescriptor, "4\0\0", 3, 0) != -1) {
		if (recv(fileDescriptor, bufRespuesta, 2, 0) != -1) {
			if ((bufRespuesta[0] == 's') && (bufRespuesta[1] == 'i')) {
				boolean = 1;
			}
		}
	}
	return boolean;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                              MATAR NODO                                             */
/* --------------------------------------------------------------------------------------------------- */
/* Busca el nodo de la lista <ppd> cuyo identificador sea <identificador>                              */
/* Si lo encuentra, le envia hasta 4 mensajes de confirmacion con intervalos de 1500ms                 */
/* En caso de fallar las 4 confirmaciones, quita el nodo y devuelve 1                                  */
/* En caso de exito en alguna de las confirmaciones, devuelve 0                                        */
/* --------------------------------------------------------------------------------------------------- */

uint32_t matar(char *identificador, uint16_t flagConsola) {
	nodoLista *proAux = ppd;
	uint16_t boolean = 0;
	char* respuesta1 = (char*) malloc(sizeof(char) * 2);
	while (proAux != NULL && (strcmp(proAux->infoLista.id, identificador) != 0)) {
		proAux = proAux->sig;
	}
	if ((proAux != NULL) && (strcmp(proAux->infoLista.id, identificador)) == 0) {
		proAux->infoLista.fileDescriptor = conectar(proAux->infoLista.ip, proAux->infoLista.puerto);
		if (confirmacion(proAux->infoLista.fileDescriptor) == 0) {
			if (confirmacion(proAux->infoLista.fileDescriptor) == 0) {
				if (confirmacion(proAux->infoLista.fileDescriptor) == 0) {
					if (confirmacion(proAux->infoLista.fileDescriptor) == 0) {
						if (flagConsola == 1) {
							printf("Enviadas 4 confirmaciones de disponibilidad al planificador <%s> \n", proAux->infoLista.id);
							printf("No se obtuvo respuesta \n");
							printf("Eliminando Nodo \n");
						}
						close(proAux->infoLista.fileDescriptor);
						buscarQuitar(proAux->infoLista.id);
						free(respuesta1);
						boolean = 1;
					}
				}
			}
		} else {
			free(respuesta1);
			boolean = 0;
		}
	}
	return boolean;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                               POTENCIA                                              */
/* --------------------------------------------------------------------------------------------------- */
/* Eleva <base> a la <exponente> y devuelve el resultado                                               */
/* --------------------------------------------------------------------------------------------------- */

uint64_t potencia(uint16_t base, uint16_t exponente) {
	uint64_t res;
	uint16_t i;
	for (res = i = 1; i <= exponente; i++) {
		res = res * base;
	}
	return res;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                          EMPAQUETAR BUFFER                                          */
/* --------------------------------------------------------------------------------------------------- */
/* Transforma la cadena de bytes <buf> en un paquete de tipo <t_paquete> y lo devuelve                 */
/* --------------------------------------------------------------------------------------------------- */

t_paquete empaquetar(char* buf) {
	t_paquete nuevoPaquete;
	char* tresPrimeros = (char*) malloc(sizeof(char) * 3);
	memcpy(tresPrimeros, buf, 3);
	nuevoPaquete.type = tresPrimeros[0];
	nuevoPaquete.pLength = (tresPrimeros[1] * 256) + tresPrimeros[2];
	nuevoPaquete.payLoad = (char*) malloc(sizeof(char) * nuevoPaquete.pLength);
	memcpy(nuevoPaquete.payLoad, buf + 3, nuevoPaquete.pLength);
	free(tresPrimeros);
	return nuevoPaquete;
}

/* --------------------------------------------------------------------------------------------------- */
/*                                 PARSEO DEL ARCHIVO DE CONFIGURACION                                 */
/* --------------------------------------------------------------------------------------------------- */
/* Lee el archivo ubicado en <path> y extrae <puerto> y <flag>                                         */
/* --------------------------------------------------------------------------------------------------- */

void parsearConfiguracion(char* path, char** puerto, uint8_t* flag) {
	FILE *archivoConfiguracion = fopen(path, "r");
	uint32_t sizeArchivo;
	char caracter;
	while (!feof(archivoConfiguracion)) {
		fread(&caracter, 1, 1, archivoConfiguracion);
		if (caracter != ' ') {
			sizeArchivo++;
		}
	}
	sizeArchivo++;
	char *contenido = (char*) malloc(sizeof(char) * sizeArchivo);
	uint32_t i = 0;
	fclose(archivoConfiguracion);
	archivoConfiguracion = fopen(path, "r");
	while (!feof(archivoConfiguracion)) {
		fread(&caracter, 1, 1, archivoConfiguracion);
		if (caracter != ' ') {
			contenido[i] = caracter;
			i++;
		}
	}
	fclose(archivoConfiguracion);
	uint32_t j = 0;
	while (contenido[j] != ':') {
		j++;
	}
	j++;
	uint32_t k = j;
	uint32_t sizePuerto = 0;
	while (contenido[j] != '\n') {
		sizePuerto++;
		j++;
	}

	(*puerto) = (char*) malloc(sizeof(char) * sizePuerto);
	(*puerto)[sizePuerto] = '\0';
	uint32_t l = 0;
	while (contenido[k] != '\n') {
		(*puerto)[l] = contenido[k];
		k++;

		l++;
	}
	k++;
	while (contenido[k] != ':') {
		k++;
	}
	k++;
	char *flagAux = (char*) malloc(2);
	flagAux[0] = contenido[k];
	flagAux[1] = '\0';
	(*flag) = atoi(flagAux);
	free(flagAux);
	free(contenido);
}

void imprimirLista(void) {
	nodoLista *aux = (nodoLista*) malloc(sizeof(nodoLista));
	aux = ppd;
	uint32_t nodoNumero = 1;
	printf("[ppd] ");
	while (aux != NULL) {
		if (nodoNumero == 1) {
			printf("--> [ Nodo %d | ID(%s) | FD(%d) | TE(%d) | IP(%s) | P(%i) ] \n", nodoNumero, aux->infoLista.id, aux->infoLista.fileDescriptor, aux->infoLista.tiempoDeEspera, aux->infoLista.ip, aux->infoLista.puerto);
		} else {
			printf("               |\n");
			printf("               V\n");
			printf("          [ Nodo %d | ID(%s) | FD(%d) | TE(%d) | IP(%s) | P(%i) ] \n", nodoNumero, aux->infoLista.id, aux->infoLista.fileDescriptor, aux->infoLista.tiempoDeEspera, aux->infoLista.ip, aux->infoLista.puerto);
		}
		nodoNumero++;
		aux = aux->sig;
	}
	printf("\n");
}
/* --------------------------------------------------------------------------------------------------- */
/*                                       PROCESAR NUEVO PAQUETE                                        */
/* --------------------------------------------------------------------------------------------------- */
/* Analiza el contenido del paquete <paquete>                                                          */
/* Si es de tipo 0, con payLoad vacio, devuelve "FS"                                                   */
/* Si es de tipo 0, con payLoad no vacio, devuelve el contenido del payLoad                            */
/* Si es de tipo 1, devuelve el string "Lei"                                                           */
/* Si es de tipo 2, devuelve el string "Escribi"                                                       */
/* --------------------------------------------------------------------------------------------------- */

void procesarPaquete(t_paquete paquete, char **respuesta, char **identificador, uint64_t *sectores, char **ip, uint32_t *puerto, uint32_t *idSize, uint32_t *ipSize) {
	if (paquete.type == 0) {
		if (paquete.pLength != 0) {
			(*respuesta) = (char*) malloc(sizeof(char) * 4);
			(*respuesta)[0] = 'P';
			(*respuesta)[1] = 'P';
			(*respuesta)[2] = 'D';
			(*respuesta)[3] = '\0';
			uint32_t i = 0;
			while (paquete.payLoad[i] != '@') {
				i++;
			}
			*identificador = (char*) malloc(sizeof(char) * i);
			(*idSize) = i;
			i = 0;
			while (paquete.payLoad[i] != '@') {
				(*identificador)[i] = paquete.payLoad[i];
				i++;
			}
			(*identificador)[i] = '\0';
			uint64_t sectorV1 = (((uint8_t) paquete.payLoad[i + 1]) * potencia(2, 56));
			uint64_t sectorV2 = (((uint8_t) paquete.payLoad[i + 2]) * potencia(2, 48));
			uint64_t sectorV3 = (((uint8_t) paquete.payLoad[i + 3]) * potencia(2, 40));
			uint64_t sectorV4 = (((uint8_t) paquete.payLoad[i + 4]) * potencia(2, 32));
			uint64_t sectorV5 = (((uint8_t) paquete.payLoad[i + 5]) * potencia(2, 24));
			uint64_t sectorV6 = (((uint8_t) paquete.payLoad[i + 6]) * potencia(2, 16));
			uint64_t sectorV7 = (((uint8_t) paquete.payLoad[i + 7]) * potencia(2, 8));
			uint64_t sectorV8 = (((uint8_t) paquete.payLoad[i + 8]) * potencia(2, 0));
			(*sectores) = sectorV1 + sectorV2 + sectorV3 + sectorV4 + sectorV5 + sectorV6 + sectorV7 + sectorV8;
			i = i + 10;
			uint32_t iViejo = i;
			uint32_t malloc1;
			uint32_t j = 0;
			while (paquete.payLoad[i] != '@') {
				malloc1++;
				i++;
			}
			(*ip) = (char*) malloc(sizeof(char) * malloc1);
			(*ipSize) = malloc1;
			while (paquete.payLoad[iViejo] != '@') {
				(*ip)[j] = paquete.payLoad[iViejo];
				j++;
				iViejo++;
			}
			(*ip)[iViejo] = '\0';
			i++;
			uint32_t iViejo2 = i;
			uint32_t malloc2 = 1;
			uint32_t z = 0;
			while (paquete.payLoad[i] != '@') {
				malloc2++;
				i++;
			}
			char *puertoAux = (char*) malloc(sizeof(char) * malloc2);
			while (paquete.payLoad[iViejo2] != '@') {
				puertoAux[z] = paquete.payLoad[iViejo2];
				z++;
				iViejo2++;
			}
			puertoAux[iViejo2] = '\0';
			(*puerto) = atoi(puertoAux);
		} else {
			if (paquete.pLength == 0) {
				(*respuesta) = (char*) malloc(sizeof(char) * 3);
				(*respuesta)[0] = 'F';
				(*respuesta)[1] = 'S';
				(*respuesta)[2] = '\0';
			}
		}
	} else {
		if (paquete.type == 1) {
			*respuesta = (char*) malloc(sizeof(char) * 4);

			strcpy(*respuesta, "Lei");
		} else {
			if (paquete.type == 2) {
				*respuesta = (char*) malloc(sizeof(char) * 8);
				strcpy(*respuesta, "Escribi");
			}
		}
	}
}
